<?php
namespace App\Models\System;

use App\Exceptions\ApiException;
use App\Providers\LengthAwarePaginatorProvider;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Enums\System\SysOperLog\{BusinessType, OperatorType, Status};

/**
* 操作日志记录 模型
* @create 2023-08-22 16:59:20
*/
class SysOperLogModel extends \App\Models\BaseModel {
    use HasFactory;

    const Table         = "sys_oper_log";
    const PrimaryKey    = "oper_id";
    public $timestamps  = false;

    static $Wheres = ['oper_id','business_type','operator_type','status'];     // 直接定义column, 默认where(column, '=', value)
    public function __construct($attributes = []) {
        parent::__construct($attributes);

        // static::$Wheres['oper_id']   = fn($q, $v) => $q->where(atn('oper_id'), '=', $v);
        static::$Wheres['title']   = fn($q, $v) => $q->where(atn('title'), '=', "%{$v}%");
        static::$Wheres['oper_name']   = fn($q, $v) => $q->where(atn('oper_name'), '=', "%{$v}%");
        static::$Wheres['begin_time']   = fn($q, $v) => $q->whereDate(atn('create_time'), '>=', $v);    // ymd
        static::$Wheres['end_time']     = fn($q, $v) => $q->whereDate(atn('create_time'), '<=', $v);    // ymd
    }

    /** xxxx */
    // public function user() {
        // return $this->hasOne(User::class, 'id', 'uid');
    // }

    /** ========== 常用查询 ========== */
    static $Vo  = ['oper_id','title','business_type','method','request_method','operator_type','oper_name','dept_name','oper_url','oper_ip','oper_location','oper_param','json_result','status','error_msg','oper_time',];
    static $Voi = ['*', ];

    /**
     * 新增操作日志
     * 
     * @param $operLog 操作日志对象
     */
    public function insertOperlog($operLog): SysOperLogModel {
        $values = static::when(
                    $operLog,
                    'title',
                    'business_type',
                    'method',
                    'request_method',
                    'operator_type',
                    'oper_name',
                    'dept_name',
                    'oper_url',
                    'oper_ip',
                    'oper_location',
                    'oper_param',
                    'json_result',
                    'status',
                    'error_msg',
                );
        $values['oper_time'] = Carbon::now();
        return throw_str(
            static::row_add($values)
        );
    }

    /**
     * 查询系统操作日志集合
     * 
     * @param $operLog 操作日志对象
     * @return SysOperLogModel[]|Collection 操作日志集合
     */
    public function selectOperLogList(array $operLog=null): Collection {
        $businessTypes = get_value($operLog, 'businessTypes');
        return $this->selectVo()
            ->whers($operLog, 'title', 'business_type', 'status', 'oper_name', 'begin_time', 'end_time')
            ->when($businessTypes && count($businessTypes)>0, fn($q)=>$q->whereIn(atn('business_type'), $businessTypes))
            ->orderBy(atn('oper_id'))
            ->get()
            ;
    }

    /**
     * 批量删除系统操作日志
     * 
     * @param $operIds 需要删除的操作日志ID
     * @return int 结果
     */
    public function deleteOperLogByIds(array $operIds): int {
        return $this
            ->whereIn('oper_id', $operIds)
            ->delete()
            ;
    }

    /**
     * 查询操作日志详细
     * 
     * @param $operId 操作ID
     * @return SysOperLogModel 操作日志对象
     */
    public function selectOperLogById($operId): SysOperLogModel {
        return throw_str(
            $this->selectVo()
                ->where(atn('oper_id'), '=', $operId)
                ->first() 
            ?? "操作日志({$operId})查找失败"
        );
    }

    /**
     * 清空操作日志
     */
    public function cleanOperLog() {
        return $this
            ->truncate()
            ;
    }

    /** 根据OperId获取 */
    public function selectByOperId($oper_id): SysOperLogModel {
        $where = [['oper_id', '=', "{$oper_id}"]];
        return throw_str(
            static::row($where) ?? "数据($oper_id)为空~"
        );
    }


    /** 获取列表 @return SysOperLog[]+paginator() */
    public function selectList(int|array $pag=1, array $param=[]): LengthAwarePaginatorProvider {
        return static::rows_pag($pag, [], fn($q)=>$q
                    // ->when(isset($param['oper_id']), fn($q)=>$q->where('oper_id', '=', $param['oper_id']))
                    ->wheres($param, 'oper_id','business_type','operator_type','status')
                    ->orderByDesc("oper_id")
        );
    }


    /** 插入数据 */
    public function insertData(array $data): SysOperLogModel {
        return throw_str(
            static::row_add([
                // 'oper_id'            => $data['oper_id'],
                'title'                 => $data['title'] ?? '',
                'business_type'         => $data['business_type'] ?? '0',
                'method'                => $data['method'] ?? '',
                'request_method'        => $data['request_method'] ?? '',
                'operator_type'         => $data['operator_type'] ?? '0',
                'oper_name'             => $data['oper_name'] ?? '',
                'dept_name'             => $data['dept_name'] ?? '',
                'oper_url'              => $data['oper_url'] ?? '',
                'oper_ip'               => $data['oper_ip'] ?? '',
                'oper_location'         => $data['oper_location'] ?? '',
                'oper_param'            => $data['oper_param'] ?? '',
                'json_result'           => $data['json_result'] ?? '',
                'status'                => $data['status'] ?? '0',
                'error_msg'             => $data['error_msg'] ?? '',
                'oper_time'             => $data['oper_time'] ?? '',
            ])
        );
    }


    /** 更新数据 */
    public function updateData(int|array $idOrWhere, array $data): SysOperLogModel {
        $values = static::when(
                    $data, 
                    // 'oper_id',
                    'title',
                    'business_type',
                    'method',
                    'request_method',
                    'operator_type',
                    'oper_name',
                    'dept_name',
                    'oper_url',
                    'oper_ip',
                    'oper_location',
                    'oper_param',
                    'json_result',
                    'status',
                    'error_msg',
                    'oper_time',
                );
        return throw_str(
            static::row_update($idOrWhere, $values)
        );
    }


    /** 删除数据 */
    public function deleteData(int|array $idOrWhere): SysOperLogModel {
        return throw_str(
            static::row_delete($idOrWhere)
        );
    }



}